/*
 *      net-sim - link
 *
 * 		Link.java
 *
 *      Copyright 23/12/2008 nicolas
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 3 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */
package link;

import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import net_interfaces.Interface;
import exceptions.NodeException;

// TODO: Auto-generated Javadoc
/**
 * The Class Link.
 */
public class Link {
  // Socket y direcciones local y remota del soporte UDP
  /** Direccion local del UDP */
  InetAddress localaddr = null;

  /** The localport. */
  public int localport = 0;;

  /** Direccion remota del UDP. */
  InetAddress remoteaddr = null;

  /** The remoteport. */
  public int remoteport = 0;

  /** Socket UDP soporte de comunicaciones sobre el link. */
  DatagramSocket socket;

  /** Thread receptor del link. */
  Linkreceiver receiver;

  /** Thread emisor del link. */
  Linksender sender ;

  /** Interfaz asociada al link. */
  Interface intf = null;


  /**
   * Instantiates a new link.
   * este es asociandolo con las direcciones local y remota
   * (esto cambiara con links de acceso multiple)
   *
   * @param laddr the laddr
   * @param lport the lport
   * @param raddr the raddr
   * @param rport the rport
   *
   * @throws NodeException the node exception
   */
  public Link(String laddr, String lport, String raddr, String rport) throws NodeException {

    getremoteaddr(laddr, lport);
    getlocaladdr(raddr, rport);

    try {
      socket = new DatagramSocket(localport,localaddr);    // Crea el socket
    }
    catch(SocketException e) {
      String d = localaddr.getHostName() + " - " + localaddr.getCanonicalHostName() + ":" + localport;
      throw new NodeException(NodeException.SOCKETERROR, d);
    }

    receiver = new Linkreceiver(this, socket);                         //Thread recepcion
    sender = new Linksender(this, socket, remoteaddr, remoteport);     // Thread emision
    System.out.println("Creado link, origen: "+laddr+":"+lport+"  Destino: "+raddr+":"+rport);
  }


  /**
   * Configura la interfaz local asociada al link
   *
   * @param inf the new interface
   */
  public void setInterface(Interface inf) {
    intf = inf;
    sender.setQueue(intf.getsendQueue());
    }


  /**
   * Receive.
   * Agrega un segmento a la cola de segmentos de control
   * El frame recibido tiene ya la encapsulacion a nivel link, realizada por la interfaz
   * public void addFrame(byte[] frame)
   * Recepcion de frame, invoca a la interfaz
   *
   * @param bb the bb
   */
  public void receive( byte[] bb) {
    System.out.println("recibe en LINK"+ bb[4]+bb[5]+bb[6]+bb[7]);
    if (intf != null) intf.receive(bb);
  }


  /**
   *  A partir de los strings direccion-port obtiene las direcciones (InetAddress y ports).
   *
   * @param addr the addr
   * @param prt the prt
   *
   * @return the localaddr
   *
   * @throws NodeException the node exception
   */
  public void getlocaladdr(String addr, String prt) throws NodeException {
   try {
     localport = Integer.parseInt(prt);
     localaddr = InetAddress.getByName(addr);
   }
   catch(UnknownHostException e) {
     throw new NodeException(NodeException.UNKNOWNHOST, addr);
   }
   catch(NumberFormatException e)  {
     throw new NodeException(NodeException.BADPORT, prt);
   }
  }

  /**
   *  A partir de los strings direccion-port obtiene las direcciones (InetAddress y ports).
   *
   * @param addr the addr
   * @param prt the prt
   *
   * @return the remoteaddr
   *
   * @throws NodeException the node exception
   */
  public void getremoteaddr(String addr, String prt) throws NodeException {
   try {
     remoteport = Integer.parseInt(prt);
     remoteaddr = InetAddress.getByName(addr);
   }
   catch(UnknownHostException e) {
     throw new NodeException(NodeException.UNKNOWNHOST, addr);
   }
   catch(NumberFormatException e)  {
     throw new NodeException(NodeException.BADPORT, prt);
   }
  }
}



